<?php
if (!defined('FosfoaSystem')) {
    exit(1);
}
import($GLOBALS['spConfig']['controller_path'] . '/general.php');
/**
 * ALIPAY支付控制器
 * @author Fosf
 * @version 1.0
 * @created 2011-04-11
 */
class alipay extends general
{
    var $Alipayconfig;
    var $Alipay_login_config;
    function __construct()
    {
        parent::__construct();
        //ALIPAY支付
        $alipay_config['partner'] = ALIPAY_PARTNER;
        $alipay_config['key'] = ALIPAY_KEY;
        $alipay_config['seller_email'] = ALIPAY_EMAIL;
        $alipay_config['return_url'] = "http://" . $_SERVER["HTTP_HOST"] . spUrl('alipay','returnurl');
        $alipay_config['notify_url'] = "http://" . $_SERVER["HTTP_HOST"] . spUrl('alipay','notifyurl');
        $alipay_config['sign_type'] = 'MD5';
        $alipay_config['input_charset'] = 'utf-8';
        $alipay_config['transport'] = 'http';
        $this->Alipayconfig = $alipay_config;
        
        //ALIPAY快捷登录
        $alipay_login_config['partner']      = ALIPAY_PARTNER;
        $alipay_login_config['key']          = ALIPAY_KEY;
        $alipay_login_config['return_url']   = "http://" . $_SERVER["HTTP_HOST"] . spUrl('alipay','loginreturnurl');
        $alipay_login_config['sign_type']    = 'MD5';
        $alipay_login_config['input_charset']= 'utf-8';
        $alipay_login_config['transport']    = 'http';
        $this->Alipay_login_config = $alipay_login_config;
        
        
        

    }
    /**
     * ALIPAY 快捷登入
     */
    function login()
    {
        $alipay_login_config = $this->Alipay_login_config;
        import("alipay/lib/alipay_service.class.php");
        /**************************请求参数**************************/

        //选填参数//

        //防钓鱼时间戳
        $anti_phishing_key = '';
        //获取客户端的IP地址，建议：编写获取客户端IP地址的程序
        $exter_invoke_ip = getIP();
        //注意：
        //1.请慎重选择是否开启防钓鱼功能
        //2.exter_invoke_ip、anti_phishing_key一旦被使用过，那么它们就会成为必填参数
        //3.开启防钓鱼功能后，服务器、本机电脑必须支持SSL，请配置好该环境。
        //示例：
        //$exter_invoke_ip = '202.1.1.1';
        //$ali_service_timestamp = new AlipayService($aliapy_config);
        //$anti_phishing_key = $ali_service_timestamp->query_timestamp();//获取防钓鱼时间戳函数

        /************************************************************/

        //构造要请求的参数数组
        $parameter = array(
            "service" => "alipay.auth.authorize",
            "target_service" => 'user.auth.quick.login',

            "partner" => trim($alipay_login_config['partner']),
            "_input_charset" => trim(strtolower($alipay_login_config['input_charset'])),
            "return_url" => trim($alipay_login_config['return_url']),

            "anti_phishing_key" => $anti_phishing_key,
            "exter_invoke_ip" => $exter_invoke_ip);

        //构造快捷登录接口
        $alipayService = new AlipayService($alipay_login_config);
        $html_text = $alipayService->alipay_auth_authorize($parameter);
        echo $html_text;
    }
    /**
     * ALIPAY快捷登录返回信息
     */
    function loginreturnurl()
    {
        $GETarr = $this->spArgs();
        $GET = array();
        $GET['is_success'] = urldecode($GETarr['is_success']);
        $GET['notify_id'] = urldecode($GETarr['notify_id']);
        $GET['real_name'] = urldecode($GETarr['real_name']);
        $GET['token'] = urldecode($GETarr['token']);
        $GET['user_id'] = urldecode($GETarr['user_id']);
        $GET['sign'] = urldecode($GETarr['sign']);
        $GET['sign_type'] = urldecode($GETarr['sign_type']);
        //dump($this->spArgs());
        //dump($GET);
        //exit;
        $alipay_login_config = $this->Alipay_login_config;
        import("alipay/lib/alipay_notify.class.php");
        //计算得出通知验证结果
        $alipayNotify = new AlipayNotify($alipay_login_config);
        $verify_result = $alipayNotify->verifyReturn($GET);
        if($verify_result) {//验证成功
        	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        	//请在这里加上商户的业务逻辑程序代码
        	
        	//——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
            //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表
            $user_id	= $GET['user_id'];	//支付宝用户id
            $token		= $GET['token'];	//授权令牌
        
        	//执行商户的业务程序
        	
        	echo "IS OK<br />";
        	echo "token:".$token;
        
        	//etao专用
        	if($GET['target_url'] != "") {
        		//程序自动跳转到target_url参数指定的url去
        	}
        	
        	//——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
        	
        	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        }
        else {
            //验证失败
            //如要调试，请看alipay_notify.php页面的verifyReturn函数，比对sign和mysign的值是否相等，或者检查$responseTxt有没有返回true
            echo "IS ERROR";
        } 
    }

    //去支付宝支付主
    function alipayto()
    {
        $order_sn = $this->spArgs('order_sn');
        $order_id = $this->spArgs('order_id');
        $subtotal = $this->spArgs('subtotal');
        $shipping = $this->spArgs('shipping');

        $conditions = array("orders_sn" => $order_sn);
        $orderobj = spClass('orderModel');
        //判断订单是否存在
        $order = $orderobj->find($conditions);
        if ($order['orders_id']) {
            $subtotal = $order['order_total'];
            $shipping = $order['shipping_method'];
            $shippingtype = $order['shipping_module_code'];
            $order_sn = $order['orders_sn'];

        } else {
            $this->error('订单过期,请重新开始！', spUrl('main', 'ShoppingCart'));
        }
        //dump($order);
        //dump($this->spArgs());exit;
        $alipay_config = $this->Alipayconfig;
        import("alipay/lib/alipay_service.class.php");
        //请与贵网站订单系统中的唯一订单号匹配
        $out_trade_no = $order_sn;
        //订单名称，显示在支付宝收银台里的“商品名称”里，显示在支付宝的交易管理的“商品名称”的列表里。
        $subject = '订单号:' . $order_sn;
        //订单总金额，显示在支付宝收银台里的“应付总额”里
        $total_fee = $subtotal + $shipping;
        //订单描述、订单详细、订单备注，显示在支付宝收银台里的“商品描述”里
        $body = '订购商品总价:' . $subtotal . ' + ' . $shippingtype . ':' . $shipping . ' = ' .
            $total_fee;


        //扩展功能参数——默认支付方式//

        //默认支付方式，取值见“即时到帐接口”技术文档中的请求参数列表
        $paymethod = '';
        //默认网银代号，代号列表见“即时到帐接口”技术文档“附录”→“银行列表”
        $defaultbank = '';


        //扩展功能参数——防钓鱼//

        //防钓鱼时间戳
        $anti_phishing_key = '';
        //获取客户端的IP地址，建议：编写获取客户端IP地址的程序
        $exter_invoke_ip = getIP();
        //注意：
        //1.请慎重选择是否开启防钓鱼功能
        //2.exter_invoke_ip、anti_phishing_key一旦被使用过，那么它们就会成为必填参数
        //3.开启防钓鱼功能后，服务器、本机电脑必须支持SSL，请配置好该环境。
        //示例：
        //$exter_invoke_ip = '202.1.1.1';
        //$ali_service_timestamp = new AlipayService($aliapy_config);
        //$anti_phishing_key = $ali_service_timestamp->query_timestamp();//获取防钓鱼时间戳函数


        //扩展功能参数——其他//

        //商品展示地址，要用 http://格式的完整路径，不允许加?id=123这类自定义参数
        $show_url = "http://" . $_SERVER["HTTP_HOST"] . spUrl('main', 'Account');
        //自定义参数，可存放任何内容（除=、&等特殊字符外），不会显示在页面上
        $extra_common_param = '';

        //扩展功能参数——分润(若要使用，请按照注释要求的格式赋值)
        $royalty_type = ""; //提成类型，该值为固定值：10，不需要修改
        $royalty_parameters = "";
        //注意：
        //提成信息集，与需要结合商户网站自身情况动态获取每笔交易的各分润收款账号、各分润金额、各分润说明。最多只能设置10条
        //各分润金额的总和须小于等于total_fee
        //提成信息集格式为：收款方Email_1^金额1^备注1|收款方Email_2^金额2^备注2
        //示例：
        //royalty_type 		= "10"
        //royalty_parameters= "111@126.com^0.01^分润备注一|222@126.com^0.01^分润备注二"

        /************************************************************/

        //构造要请求的参数数组
        $parameter = array(
            "service" => "create_direct_pay_by_user",
            "payment_type" => "1",

            "partner" => trim($alipay_config['partner']),
            "_input_charset" => trim(strtolower($alipay_config['input_charset'])),
            "seller_email" => trim($alipay_config['seller_email']),
            "return_url" => trim($alipay_config['return_url']),
            "notify_url" => trim($alipay_config['notify_url']),

            "out_trade_no" => $out_trade_no,
            "subject" => $subject,
            "body" => $body,
            "total_fee" => $total_fee,

            "paymethod" => $paymethod,
            "defaultbank" => $defaultbank,

            "anti_phishing_key" => $anti_phishing_key,
            "exter_invoke_ip" => $exter_invoke_ip,

            "show_url" => $show_url,
            "extra_common_param" => $extra_common_param,

            "royalty_type" => $royalty_type,
            "royalty_parameters" => $royalty_parameters);

        //构造即时到帐接口
        //dump($parameter);
        //dump($alipay_config);exit;
        $alipayService = new AlipayService($alipay_config);
        $html_text = $alipayService->create_direct_pay_by_user($parameter);
        echo $html_text;
    }
    //页面跳转同步通知页面路径，要用 http://格式的完整路径，不允许加?id=123这类自定义参数
    function returnurl()
    {
        $GETarr = $this->spArgs();
        $GET = array();
        $GET['body'] = urldecode($GETarr['body']);
        $GET['buyer_email'] = urldecode($GETarr['buyer_email']);
        $GET['buyer_id'] = urldecode($GETarr['buyer_id']);
        $GET['exterface'] = urldecode($GETarr['exterface']);
        $GET['is_success'] = urldecode($GETarr['is_success']);
        $GET['notify_id'] = urldecode($GETarr['notify_id']);
        $GET['notify_time'] = urldecode($GETarr['notify_time']);
        $GET['notify_type'] = urldecode($GETarr['notify_type']);
        $GET['out_trade_no'] = urldecode($GETarr['out_trade_no']);
        $GET['payment_type'] = urldecode($GETarr['payment_type']);
        $GET['seller_email'] = urldecode($GETarr['seller_email']);
        $GET['seller_id'] = urldecode($GETarr['seller_id']);
        $GET['subject'] = urldecode($GETarr['subject']);
        $GET['total_fee'] = urldecode($GETarr['total_fee']);
        $GET['trade_no'] = urldecode($GETarr['trade_no']);
        $GET['trade_status'] = urldecode($GETarr['trade_status']);
        $GET['sign'] = urldecode($GETarr['sign']);
        $GET['sign_type'] = urldecode($GETarr['sign_type']);
        $_SESSION['orders_id'] = '';
        $_SESSION['orders_sn'] = '';
        $alipay_config = $this->Alipayconfig;
        import("alipay/lib/alipay_notify.class.php");
        // * 该页面可以使用PHP开发工具调试，也可以使用写文本函数logResult，该函数已被默认关闭，见alipay_notify_class.php中的函数verifyReturn
        //
        // * TRADE_FINISHED(表示交易已经成功结束，并不能再对该交易做后续操作);
        // * TRADE_SUCCESS(表示交易已经成功结束，可以对该交易做后续操作，如：分润、退款等);

        //计算得出通知验证结果

        $alipayNotify = new AlipayNotify($alipay_config);
        $verify_result = $alipayNotify->verifyReturn($GET);
        //echo $verify_result;
        //$verify_result = true;
        if ($verify_result) { //验证成功

            //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表
            $order_sn = $GET['out_trade_no']; //获取订单号
            $trade_no = $GET['trade_no']; //获取支付宝交易号
            $total_fee = $GET['total_fee']; //获取总价格

            $conditions = array("orders_sn" => $order_sn);
            //检查定单是否存在
            $order = spClass('orderModel')->find($conditions);
            //dump($order);
            if (!$order['orders_id'] && $total_fee != ($order['order_total'] + $order['shipping_method'])) {
                $this->jump(spUrl('main', 'CheckoutSuccess') . '?code=payerror');
                exit;
            }


            if ($GET['trade_status'] == 'TRADE_FINISHED' || $GET['trade_status'] ==
                'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                if ($order['orders_status'] != 2) {
                    $order_status = 2;
                    //存在就修改订单数据
                    $data = array(
                        'orders_status' => $order_status,
                        'rppay_id' => $GET['trade_no'],
                        'last_modified' => time());
                    spClass('orderModel')->update_order($data, $order_sn, $order['orders_id']);

                    //订单的交易过程
                    $comments = '<br/>支付宝交易号:' . $GET['trade_no'] . ' - 时间:' . $GET['notify_time'] .
                        '<br/>' . '支付宝付款帐号:' . $GET['buyer_email'] . ' 支付宝ID:' . $GET['buyer_id'] .
                        '<br/>' . $GET['subject'] . ' ' . $GET['body'] . '<br/>交易返回状态:' . $GET['trade_status'];
                    $data2 = array(
                        'orders_sn' => $order_sn,
                        'orders_status_id' => $order_status,
                        'comments' => $comments,
                        'date_added' => time());
                    spClass('orders_status_historyModel')->Create($data2);

                    $customers_basket = spClass('customers_basketModel');
                    $customers_id = $order['customers_id']; //此数据来自初始化
                    $conditions = array('customers_id' => $customers_id);
                    $customers_basket->delete($conditions); // 删除记录
                }
                //这里将放置付款成功提醒邮件
                $ordermail = spClass('email_templateModel')->order_send($order_sn); //发送订单邮件

                $this->jump(spUrl('main', 'CheckoutSuccess'));
            } else {
                echo "trade_status=" . $GET['trade_status'];
            }

        } else {
            //验证失败
            //如要调试，请看alipay_notify.php页面的verifyReturn函数，比对sign和mysign的值是否相等，或者检查$responseTxt有没有返回true
            //$this->jump(spUrl('main', 'CheckoutSuccess') . '?code=payerror');
        }

    }
    //服务器异步通知页面路径，要用 http://格式的完整路径，不允许加?id=123这类自定义参数
    function notifyurl()
    {
        // * 创建该页面文件时，请留心该页面文件中无任何HTML代码及空格。
        // * 该页面不能在本机电脑测试，请到服务器上做测试。请确保外部可以访问该页面。
        // * 该页面调试工具请使用写文本函数logResult，该函数已被默认关闭，见alipay_notify_class.php中的函数verifyNotify
        // * 如果没有收到该页面返回的 success 信息，支付宝会在24小时内按一定的时间策略重发通知
        //
        // * TRADE_FINISHED(表示交易已经成功结束，并不能再对该交易做后续操作);
        // * TRADE_SUCCESS(表示交易已经成功结束，可以对该交易做后续操作，如：分润、退款等);
        //计算得出通知验证结果
        $POST = $this->spArgs();
        $GET = array();
        $GET['body'] = urldecode($POST['body']);
        $GET['buyer_email'] = urldecode($POST['buyer_email']);
        $GET['buyer_id'] = urldecode($POST['buyer_id']);
        $GET['exterface'] = urldecode($POST['exterface']);
        $GET['is_success'] = urldecode($POST['is_success']);
        $GET['notify_id'] = urldecode($POST['notify_id']);
        $GET['notify_time'] = urldecode($POST['notify_time']);
        $GET['notify_type'] = urldecode($POST['notify_type']);
        $GET['out_trade_no'] = urldecode($POST['out_trade_no']);
        $GET['payment_type'] = urldecode($POST['payment_type']);
        $GET['seller_email'] = urldecode($POST['seller_email']);
        $GET['seller_id'] = urldecode($POST['seller_id']);
        $GET['subject'] = urldecode($POST['subject']);
        $GET['total_fee'] = urldecode($POST['total_fee']);
        $GET['trade_no'] = urldecode($POST['trade_no']);
        $GET['trade_status'] = urldecode($POST['trade_status']);
        $GET['sign'] = urldecode($POST['sign']);
        $GET['sign_type'] = urldecode($POST['sign_type']);

        $alipay_config = $this->Alipayconfig;
        import("alipay/lib/alipay_notify.class.php");
        $alipayNotify = new AlipayNotify($alipay_config);
        $verify_result = $alipayNotify->verifyNotify($GET);

        if ($verify_result) { //验证成功
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //请在这里加上商户的业务逻辑程序代

            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
            //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表
            $order_sn = $GET['out_trade_no']; //获取订单号
            $trade_no = $GET['trade_no']; //获取支付宝交易号
            $total_fee = $GET['total_fee']; //获取总价格

            $conditions = array("orders_sn" => $order_sn);
            //检查定单是否存在
            $order = spClass('orderModel')->find($conditions);
            //dump($order);

            if ($total_fee != ($order['order_total'] + $order['shipping_method'])) {
                echo "fail";
                exit;
            }
            if ($order['orders_status'] == 2) {
                echo "success";
                exit;
            }
            if ($GET['trade_status'] == 'TRADE_FINISHED') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //该种交易状态只在两种情况下出现
                //1、开通了普通即时到账，买家付款成功后。
                //2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。

                //调试用，写文本函数记录程序运行情况是否正常
                //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
            } else
                if ($GET['trade_status'] == 'TRADE_SUCCESS') {
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序

                    //注意：
                    //该种交易状态只在一种情况下出现——开通了高级即时到账，买家付款成功后。

                    //调试用，写文本函数记录程序运行情况是否正常
                    //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
                    if ($order['orders_status'] != 2) {
                        $order_status = 2;
                        //存在就修改订单数据
                        $data = array(
                            'orders_status' => $order_status,
                            'rppay_id' => $GET['trade_no'],
                            'last_modified' => time());
                        spClass('orderModel')->update_order($data, $order_sn, $order['orders_id']);

                        //订单的交易过程
                        $comments = '异步通知交易 <br/>支付宝交易号:' . $GET['trade_no'] . ' - 时间:' . $GET['notify_time'] .
                            '<br/>' . '支付宝付款帐号:' . $GET['buyer_email'] . ' 支付宝ID:' . $GET['buyer_id'] .
                            '<br/>' . $GET['subject'] . ' ' . $GET['body'] . '<br/>交易返回状态:' . $GET['trade_status'];
                        $data2 = array(
                            'orders_sn' => $order_sn,
                            'orders_status_id' => $order_status,
                            'comments' => $comments,
                            'date_added' => time());
                        spClass('orders_status_historyModel')->Create($data2);

                        $customers_basket = spClass('customers_basketModel');
                        $customers_id = $order['customers_id']; //此数据来自初始化
                        $conditions = array('customers_id' => $customers_id);
                        $customers_basket->delete($conditions); // 删除记录
                        //这里将放置付款成功提醒邮件
                        //$ordermail = spClass('email_templateModel')->order_send($order_sn); //发送订单邮件
                    }
                }
            echo "success"; //请不要修改或删除
        } else {
            //验证失败
            echo "fail";
        }
    }
}
